﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using IronPython.Hosting;
using MetaNote.Model;
using Microsoft.Scripting.Hosting;
using Microsoft.Scripting;
using System.Drawing;
using System.IO;
namespace MetaNote.Controls
{
    public partial class CodeEditPanel : UserControl
    {
        public delegate void CodeSaveHandler(object sender, CodeSaveArgs e);
        public delegate void MacroSelectionChangedHandler(object sender, MacroSelectionChangedArgs e);

        public ToolStripItem ControlBeingEdited { get; private set; }

        /// <summary>
        /// Occurs when the code is saved.
        /// </summary>
        public event CodeSaveHandler SaveCode;

        public event MacroSelectionChangedHandler MacroSelectionChanged;

        private NiceTextBox txt1;

        public CodeEditPanel()            
        {
            InitializeComponent();            
        }

        public CodeEditPanel(NiceTextBox txt1, string title, List<Macro> macros, ToolStripItem controlBeingEdited)
            : this()
        {

            this.txt1 = txt1;
            this.ControlBeingEdited = controlBeingEdited;
            //this.titleTextBox.Text = title;
            Populate(macroTitleCombo, macros);
            macroTitleCombo.Text = title;
            this.txt1.SetMainCodeLanguage("Python"); 
        }

        private void Populate(ComboBox macroTitleCombo, List<Macro> macros)
        {
            macroTitleCombo.Items.AddRange(macros.ToArray()); 
        }

        private void saveButton_Click(object sender, EventArgs e)
        {
            //TODO: macro validation: name is required.
            var name = macroTitleCombo.Text;

            var macro = macroTitleCombo.SelectedItem as Macro;

            if (macro == null)
            {
                //it's a new macro.
                //all we have is a name.
                macro = new Macro();
                macro.Key = Guid.NewGuid();
                macro.Title = macroTitleCombo.Text;
            }
            
            macro.SourceCode = txt1.Text;

            Image image = pictureBox1.Image;
            var codeargs = new CodeSaveArgs(name, txt1, image, macro, this.ControlBeingEdited);
            
            if (SaveCode != null)
                SaveCode(sender, codeargs);
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            var dlg = new OpenFileDialog();
            dlg.DefaultExt = "png";
            dlg.Filter = "Image Files (*.gif;*.jpg;*.jpeg;*.bmp;*.wmf;*.png)|*.gif;*.jpg;*.jpeg;*.bmp;*.wmf;*.png|All Files(*.*)|*.*";
            dlg.InitialDirectory = Common.Settings.LastPicturePath;
            dlg.Multiselect = false;
            if (dlg.ShowDialog(this) != DialogResult.OK) return;
            
            Common.Settings.LastPicturePath = Path.GetFullPath(dlg.FileName);
            var fs = new FileStream(dlg.FileName, FileMode.Open, FileAccess.Read);
            pictureBox1.Image = new Bitmap(fs);
            pictureBox1.BorderStyle = BorderStyle.None;
        }

        private void macroTitleCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            var macro = macroTitleCombo.SelectedItem as Macro;
            if (macro == null)
            {
                macro = new Macro();
                macro.Title = macroTitleCombo.Text;
            }

            txt1.Text = macro.SourceCode;
            //TODO: tell the outside world that the choice of macro
            // being edited has changed... 
            //(Thus the title of this tab will change, and the highlighting 
            // of any buttons related to this new 'macro under edit' must be set.
            // and highlighting of buttons related to the previous 'macro under edit' 
            // must be cleared.)(The main button that instigated this edit has *not* changed.
            // (I do have a delegate type for this:
            //      MacroSelectionChangedHandler
            // just need to wire it up and have someone use it.
        }
    }

    public class CodeSaveArgs : EventArgs
    {
        public string Name { get; private set; }
        public NiceTextBox TextBox { get; private set; }
        public Image Image { get; private set; }
        public Macro Macro { get; private set; }
        public ToolStripItem Button { get; private set; }
        public CodeSaveArgs(string name, NiceTextBox txt1, Image image, Macro macro, ToolStripItem button)
        {
            this.Name = name;
            this.TextBox = txt1;
            this.Image = image;
            this.Macro = macro;
            this.Button = button;
        }
    }
    public class MacroSelectionChangedArgs : EventArgs
    {
        public string MacroName { get; private set; }
        public Macro Macro { get; private set; }

        public MacroSelectionChangedArgs(string macroName, Macro macro)
        {
            this.MacroName = macroName;
            this.Macro = macro;
        }
    }
}
